package com.xmall.sys.service.impl.other;

import com.alibaba.fastjson.JSON;
import com.xmall.define.base.Result;
import com.xmall.define.constants.CommonConstants;
import com.xmall.define.request.sys.TimerTaskQueryRequest;
import com.xmall.sys.service.other.ITimerTaskService;
import com.xmall.timer.dto.TimerTaskDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class TimerTaskServiceImpl implements ITimerTaskService {

    @Resource
    private DiscoveryClient client;

    @Resource
    private RestTemplate restTemplate;

    /**
     * 执行任务
     */
    @Override
    public void executeOnce(TimerTaskQueryRequest request) {
        try {
            restTemplate.postForObject(request.getServiceIp() + CommonConstants.TimerTask.TIMER_TASK_EXECUTE_ONCE_REQUEST_URL, null, Result.class, request.getTaskKey());
        }catch (Exception e) {
            log.error("remote service for executeOnce error: {}, ip: {}, taskKey: {}", e.getMessage(), request.getServiceIp(), request.getTaskKey());
        }
    }

    /**
     * 任务列表
     */
    @Override
    public List<TimerTaskDto> taskList() {
        List<TimerTaskDto> timerTaskDtoList = new ArrayList<>();

        client.getServices().forEach(service -> {
            client.getInstances(service).forEach(instance -> {
                try {
                    String serviceIp = (instance.isSecure() ? "https" : "http") + "://" + instance.getHost() + ":" + instance.getPort();
                    String requestUrl = serviceIp + CommonConstants.TimerTask.TIMER_TASK_LIST_REQUEST_URL;

                    Result<String> result = restTemplate.getForObject(requestUrl, Result.class);
                    if(result.callSuccess()) {
                        JSON.parseArray(result.getData(), TimerTaskDto.class).forEach(taskDto -> {
                            taskDto.setServiceName(service);
                            taskDto.setServiceIp(serviceIp);
                            timerTaskDtoList.add(taskDto);
                        });
                    }
                }catch (Exception e) {
                    if(!(e instanceof HttpClientErrorException.NotFound)) {
                        log.error("remote service for taskList error: {}, service: {}, ip: {}", e.getMessage(), service, instance.getHost() + ":" + instance.getPort());
                    }
                }
            });
        });

        return timerTaskDtoList;
    }

}
